---
title: >-
  为什么将 CSS `<link>` 放置在 `<head></head>` 之间，而 JS `<script>` 放置在 `</body>`
  之前是一个好主意？
subtitle: 你知道任何例外情况吗？
---

简而言之，这种 CSS `<link>` 和 JavaScript `<script>` 的放置方式可以更快地渲染页面并获得更好的整体性能。

## 将 `<link>` 放置在 `<head>` 中

将 `<link>` 放在 `<head>` 中是构建优化网站的正确规范的一部分。当页面首次加载时，HTML 和 CSS 会同时被解析；HTML 创建 DOM（文档对象模型），CSS 创建 CSSOM（CSS 对象模型）。两者都需要在网站中创建视觉效果，从而实现快速的“首次有效绘制”计时。将 CSS `<link>` 放置在 `<head>` 中可确保样式表在浏览器开始渲染页面时已加载并可以使用。

这种渐进式渲染是衡量网站性能得分的指标。将样式表放在文档的底部会阻止许多浏览器中的渐进式渲染。某些浏览器会阻止渲染，以避免在样式更改时重新绘制页面元素。然后，用户会卡在查看空白的白页上。其他时候可能会出现未设置样式的闪烁内容 (FOUC)，这会显示未应用任何样式的网页。

## 将 `<script>` 放置在 `</body>` 之前

`<script>` 标签会阻止 HTML 解析，因为它们正在被下载和执行，这会减慢页面的显示速度。将 `<script>` 放在底部将允许首先解析 HTML 并将其显示给用户。

将 `<script>` 放置在底部的例外情况是，当您的脚本包含 `document.write()` 时，但如今使用 `document.write()` 并不是一个好习惯。此外，将 `<script>` 放置在底部意味着浏览器在整个文档被解析之前无法开始下载脚本。这确保了需要操作 DOM 元素的代码不会抛出错误并停止整个脚本。如果需要在 `<head>` 中放置 `<script>`，请使用 `defer` 属性，这将实现与仅在 HTML 被解析后运行脚本相同的效果，但浏览器可以更早地启动网络请求以下载脚本。

请记住，将脚本放在结束 `</body>` 标签之前会产生页面在空缓存上加载更快的错觉（因为脚本不会阻止下载文档的其余部分）。但是，如果您有一些代码要在页面加载期间运行，它将仅在整个页面加载完成后才开始执行。如果将这些脚本放在 `<head>` 标签中，它们将开始更早地执行 - 因此在已准备好的缓存上，页面实际上看起来会加载得更快。

## `<head>` 和 `<body>` 标签现在是可选的

根据 HTML5 规范，某些 HTML 标签（如 `<head>` 和 `<body>`）是可选的。谷歌的风格指南甚至建议删除它们以节省字节。但是，这种做法尚未得到广泛采用，性能提升可能很小，对于大多数网站来说，它可能无关紧要。
